import type { Metadata } from "next"; import Link from "next/link"; import { notFound } from "next/navigation"; import { ArrowRight, Paperclip, Swords } from "lucide-react"; import { getPublicArenaShare } from "@/lib/arena/service"; import type { ArenaShareSnapshot } from "@/lib/arena/export"; import { Logo } from "@/components/brand/logo"; import { ProviderIcon } from "@/components/brand/provider-icon"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { SimpleMarkdown } from "@/components/markdown/simple-markdown"; import { BlindNotice, SharedArenaView } from "@/components/arena/shared-arena-view"; export const dynamic = "force-dynamic"; function isRecord(v: unknown): v is Record { return typeof v === "object" && v !== null; } /** Defensive parse of the frozen snapshot written by `shareArenaSession`. */ function parseSnapshot(raw: unknown): ArenaShareSnapshot | null { if (!isRecord(raw) || typeof raw.prompt !== "string" || !Array.isArray(raw.responses)) return null; const responses = raw.responses.filter(isRecord).map((r, i) => ({ id: typeof r.id === "string" ? r.id : `r${i}`, modelKey: typeof r.modelKey === "string" ? r.modelKey : "", provider: typeof r.provider === "string" ? r.provider : (typeof r.modelKey === "string" ? r.modelKey.split("/")[0] : ""), displayName: typeof r.displayName === "string" ? r.displayName : typeof r.modelKey === "string" ? r.modelKey.split("/").slice(1).join("/") : "Model", status: typeof r.status === "string" ? r.status : "complete", content: typeof r.content === "string" ? r.content : "", reasoning: typeof r.reasoning === "string" ? r.reasoning : null, error: isRecord(r.error) && typeof r.error.message === "string" ? { code: String(r.error.code ?? "ERROR"), message: r.error.message } : null, ttftMs: typeof r.ttftMs === "number" ? r.ttftMs : null, latencyMs: typeof r.latencyMs === "number" ? r.latencyMs : null, costUsd: typeof r.costUsd === "number" ? r.costUsd : null, usage: isRecord(r.usage) ? (r.usage as ArenaShareSnapshot["responses"][number]["usage"]) : null, criteriaWon: Array.isArray(r.criteriaWon) ? r.criteriaWon.filter((c): c is string => typeof c === "string") : [], })); const models = Array.isArray(raw.models) ? raw.models.filter(isRecord).map((m) => ({ key: String(m.key ?? ""), provider: String(m.provider ?? ""), displayName: String(m.displayName ?? m.key ?? "") })) : responses.map((r) => ({ key: r.modelKey, provider: r.provider, displayName: r.displayName })); const votes = Array.isArray(raw.votes) ? raw.votes.filter(isRecord).map((v) => ({ criterion: String(v.criterion ?? ""), label: String(v.label ?? v.criterion ?? ""), modelKey: String(v.modelKey ?? ""), responseId: String(v.responseId ?? "") })) : []; const w = isRecord(raw.winner) ? raw.winner : null; const winner = w && typeof w.modelKey === "string" ? { modelKey: w.modelKey, responseId: String(w.responseId ?? ""), criteriaWon: Array.isArray(w.criteriaWon) ? w.criteriaWon.filter((c): c is string => typeof c === "string") : [], tieBreak: w.tieBreak === "fastest" ? ("fastest" as const) : w.tieBreak === "order" ? ("order" as const) : null, deltas: isRecord(w.deltas) ? { costUsd: num(w.deltas.costUsd), ttftMs: num(w.deltas.ttftMs), latencyMs: num(w.deltas.latencyMs), outputTokens: num(w.deltas.outputTokens), others: num(w.deltas.others) ?? 0 } : { costUsd: null, ttftMs: null, latencyMs: null, outputTokens: null, others: 0 }, } : null; return { version: 1, prompt: raw.prompt, systemPrompt: typeof raw.systemPrompt === "string" ? raw.systemPrompt : null, blind: raw.blind === true, attachmentCount: typeof raw.attachmentCount === "number" ? raw.attachmentCount : 0, parameters: isRecord(raw.parameters) ? raw.parameters : {}, createdAt: typeof raw.createdAt === "string" ? raw.createdAt : new Date().toISOString(), models, responses, votes, winner, }; } function num(v: unknown): number | null { return typeof v === "number" && Number.isFinite(v) ? v : null; } async function getShareSafe(id: string) { if (!id || id.length > 128 || !/^[\w-]+$/.test(id)) return null; try { const row = await getPublicArenaShare(id); if (!row) return null; const snapshot = parseSnapshot(row.snapshot); return snapshot ? { row, snapshot } : null; } catch { return null; } } function title(s: ArenaShareSnapshot): string { const names = s.models.map((m) => m.displayName); return names.length <= 2 ? names.join(" vs ") : `${names.slice(0, 2).join(" vs ")} + ${names.length - 2} more`; } export async function generateMetadata({ params }: { params: Promise<{ id: string }> }): Promise { const { id } = await params; const share = await getShareSafe(id); return { title: share ? `${title(share.snapshot)} — Arena comparison` : "Shared Arena comparison", description: share ? share.snapshot.prompt.slice(0, 160) : "This shared comparison is unavailable.", robots: { index: false, follow: false, nocache: true }, openGraph: share ? { title: `${title(share.snapshot)} — PolyLLM Arena`, description: share.snapshot.prompt.slice(0, 200), type: "article" } : undefined, }; } export default async function SharedArenaPage({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; const share = await getShareSafe(id); if (!share) notFound(); const s = share.snapshot; const created = new Date(s.createdAt); const params_ = Object.entries(s.parameters).filter(([, v]) => v !== undefined && v !== null); return (
· Shared Arena comparison

Arena · {s.models.length} model{s.models.length === 1 ? "" : "s"}

{title(s)}

·
    {s.models.map((m) => (
  • {m.displayName}
  • ))}
{s.blind ? : null}

Prompt:

{s.prompt}
{s.systemPrompt || s.attachmentCount || params_.length ? (
Settings
{s.systemPrompt ? (

System prompt: {s.systemPrompt}

) : null} {s.attachmentCount ? (

{s.attachmentCount} attachment{s.attachmentCount === 1 ? "" : "s"} (not published)

) : null} {params_.length ? (
    {params_.map(([k, v]) => (
  • {k}: {typeof v === "object" ? JSON.stringify(v) : String(v)}
  • ))}
) : null}
) : null}
); }